package com.group.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.DoubleSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class MappingFastJsonHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
	private static final Logger logger = LoggerFactory.getLogger(MappingFastJsonHttpMessageConverter.class);

	public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

	private SerializerFeature[] serializerFeature;

	public SerializerFeature[] getSerializerFeature() {
		return serializerFeature;
	}

	public void setSerializerFeature(SerializerFeature[] serializerFeature) {
		this.serializerFeature = serializerFeature;
	}

	public MappingFastJsonHttpMessageConverter() {
		super(new MediaType("application", "json", DEFAULT_CHARSET));
	}

	@Override
	public boolean canRead(Class<?> clazz, MediaType mediaType) {
		return "json".equals(mediaType.getSubtype());
	}

	@Override
	public boolean canWrite(Class<?> clazz, MediaType mediaType) {
		return mediaType == null || "text".equals(mediaType.getType()) || "json".equals(mediaType.getSubtype()) || MediaType.ALL.equals(mediaType);
	}

	@Override
	protected boolean supports(Class<?> clazz) {
		throw new UnsupportedOperationException();
	}

	@Override
	protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
		ByteArrayOutputStream resultStream = new ByteArrayOutputStream();

		int i;
		// 注意body要单独get出来，不能放到while条件里面；否则当content-type
		// 为application/x-www-form-urlencoded的时候,会由于spring一直重建body而出现死循环
		InputStream body = inputMessage.getBody();
		while ((i = body.read()) != -1) {
			resultStream.write(i);
		}

		// 统一使用UTF-8编码
		String jsonStr = resultStream.toString(DEFAULT_CHARSET.name());
		if ("".equals(jsonStr))
			return null;

		logger.debug("------------- jsonStr = " + jsonStr);
		logger.debug("------------- clazz = " + clazz.getName() + "--------------" + clazz.toString());
		try {
			return JSON.parseObject(jsonStr, clazz);
		} catch (Exception e) {
			// e.printStackTrace();
			throw new NoteException("json错误,json=" + jsonStr + " , class = " + clazz.getName());
		}
	}

	@Override
	protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException {
		OutputStream out = outputMessage.getBody();

		try {
			// String jsonString = JSON.toJSONString(o, serializerFeature);
			SerializeConfig config = SerializeConfig.getGlobalInstance();
			config.put(Double.class, new DoubleSerializer("#.##############"));
			String jsonString = JSON.toJSONString(o, config, serializerFeature);
			out.write(jsonString.getBytes(DEFAULT_CHARSET));
			out.flush();
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage());
			throw new RuntimeException(e);
		}
	}
}
